class Record {
  constructor ({stream, sampleBits = 16, sampleRate = 8000} = {}) {
    this.sampleBits = sampleBits || 8
    this.sampleRate = sampleRate || (44100 / 6)
    this.context = new AudioContext()
    this.audioInput = this.context.createMediaStreamSource(stream)
    this.recorder = this.context.createScriptProcessor(4096, 1, 1)
    this.size = 0 // 录音文件长度
    this.buffer = [] // 录音缓存
    this.inputSampleRate = this.context.sampleRate // 输入采样率
    this.inputSampleBits = 16 // 输入采样数位 8, 16
    this.outputSampleRate = this.sampleRate // 输出采样率
    this.oututSampleBits = this.sampleBits // 输出采样数位 8, 16
    this.recorder.onaudioprocess = (e) => {
      this.input(e.inputBuffer.getChannelData(0))
    }
  }
  /**/
  clear () {
    this.buffer = []
    this.size = 0
  }
  input (data) {
    this.buffer.push(new Float32Array(data))
    this.size += data.length
  }
  /* 合并压缩 */
  compress () {
    // 合并
    let data = new Float32Array(this.size)
    let offset = 0
    for (let i = 0; i < this.buffer.length; i++) {
      data.set(this.buffer[i], offset)
      offset += this.buffer[i].length
    }
    // 压缩
    let compression = parseInt(this.inputSampleRate / this.outputSampleRate)
    let length = data.length / compression
    let result = new Float32Array(length)
    let index = 0
    let j = 0
    while (index < length) {
      result[index] = data[j]
      j += compression
      index++
    }
    return result
  }
  encodeWAV () {
    let sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate)
    let sampleBits = Math.min(this.inputSampleBits, this.oututSampleBits)
    let bytes = this.compress()
    let dataLength = bytes.length * (sampleBits / 8)
    let buffer = new ArrayBuffer(44 + dataLength)
    let data = new DataView(buffer)

    let channelCount = 1 // 单声道
    let offset = 0

    let writeString = function (str) {
      for (let i = 0; i < str.length; i++) {
        data.setUint8(offset + i, str.charCodeAt(i))
      }
    }

    // 资源交换文件标识符
    writeString('RIFF')
    offset += 4
    // 下个地址开始到文件尾总字节数,即文件大小-8
    data.setUint32(offset, 36 + dataLength, true)
    offset += 4
    // WAV文件标志
    writeString('WAVE')
    offset += 4
    // 波形格式标志
    writeString('fmt ')
    offset += 4
    // 过滤字节,一般为 0x10 = 16
    data.setUint32(offset, 16, true)
    offset += 4
    // 格式类别 (PCM形式采样数据)
    data.setUint16(offset, 1, true)
    offset += 2
    // 通道数
    data.setUint16(offset, channelCount, true)
    offset += 2
    // 采样率,每秒样本数,表示每个通道的播放速度
    data.setUint32(offset, sampleRate, true)
    offset += 4
    // 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8
    data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true)
    offset += 4
    // 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8
    data.setUint16(offset, channelCount * (sampleBits / 8), true)
    offset += 2
    // 每样本数据位数
    data.setUint16(offset, sampleBits, true)
    offset += 2
    // 数据标识符
    writeString('data')
    offset += 4
    // 采样数据总数,即数据总大小-44
    data.setUint32(offset, dataLength, true)
    offset += 4
    // 写入采样数据
    if (sampleBits === 8) {
      for (let i = 0; i < bytes.length; i++, offset++) {
        let s = Math.max(-1, Math.min(1, bytes[i]))
        let val = s < 0 ? s * 0x8000 : s * 0x7FFF
        val = parseInt(255 / (65535 / (val + 32768)))
        data.setInt8(offset, val, true)
      }
    } else {
      for (let i = 0; i < bytes.length; i++, offset += 2) {
        let s = Math.max(-1, Math.min(1, bytes[i]))
        data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true)
      }
    }

    return new Blob([data], {type: 'audio/wav'})
  }
  /**/
  startRecorder () {
    this.audioInput.connect(this.recorder)
    this.recorder.connect(this.context.destination)
  }
  stopRecorder () {
    this.recorder.disconnect()
  }
  getBlob () {
    return this.encodeWAV()
  }
  clearRecorder () {
    this.clear()
  }
  sendpcm (blob) {
    let oReq = new XMLHttpRequest()
    oReq.onreadystatechange = function () {
      if (oReq.readyState === 4 && (oReq.status === 200 || oReq.status === 304)) {
        // document.getElementById('message').innerHTML = oReq.responseText
        console.log('--oReq.responseText--', oReq.responseText)
      }
    }
    // let url = '/bdvoice/asr'
    let url = 'https://127.0.0.1:88/bdvoice/asr'
    oReq.open('POST', url, true)
    oReq.send(blob)
  }
}

export default Record
